import { AutoMap } from "@automapper/classes";
import {
    ArrayMinSize,
    IsArray,
    IsBoolean,
    IsEmail,
    IsIn,
    IsNotEmpty,
    IsOptional,
    Matches,
    ValidateIf
} from "class-validator";
import { Role } from "@/enums";
import { ApiProperty } from "@nestjs/swagger";

export class UpdateSelfDTO {
    @ApiProperty({
        type: String,
        description: "Имя пользователя",
        example: "Иван",
        required: false
    })
    @AutoMap()
    @IsOptional()
    firstName?: string;

    @ApiProperty({
        type: String,
        description: "Фамилия пользователя",
        example: "Иванов",
        required: false
    })
    @AutoMap()
    @IsOptional()
    lastName?: string;

    @ApiProperty({
        type: String,
        description: "Электронная почта пользователя, должна быть уникальной",
        required: false,
        example: "ivan.ivanov@example.ru"
    })
    @AutoMap()
    @IsOptional()
    @ValidateIf((_, value) => !!value)
    @IsEmail({}, { message: "Некорректный email" })
    email?: string;
}

export class UpdateAccountDTO extends UpdateSelfDTO {
    @ApiProperty({
        type: String,
        description: "Имя (логин) учетной записи, должно быть уникальным",
        required: false,
        example: "admin"
    })
    @AutoMap()
    @IsOptional()
    @ValidateIf((_, value) => !!value)
    @Matches(/^(?![_0-9])(?!.*_$)[a-zA-Z0-9_]{5,20}$/, {
        message:
            "Имя учетной записи должно быть от 5 до 20 символов и состоять из строчных или прописных латинских букв, цифр или символа нижнего подчеркивания"
    })
    userName?: string;

    @ApiProperty({
        type: String,
        description: "Пароль от учетной записи",
        required: false,
        example: "Qwerty123!"
    })
    @AutoMap()
    @IsOptional()
    @ValidateIf((_, value) => !!value)
    @Matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&#])[A-Za-z\d@$!%*?&#]{8,30}$/, {
        message:
            "Пароль должен быть от 8 до 30 символов, содержать как минимум одну цифру, строчные и прописные латинские буквы и спецсимволы"
    })
    password?: string;

    @ApiProperty({
        type: [Role],
        enum: Role,
        description: "Список ролей учетной записи",
        example: [Role.Student],
        required: false
    })
    @AutoMap()
    @IsOptional()
    @ValidateIf((_, value) => !!value)
    @IsArray({ message: "Поле roles является списком" })
    @ArrayMinSize(1, { message: "Список ролей пуст, необходимо указать хотя бы одну роль" })
    @IsIn([Role.Admin, Role.Teacher, Role.Student], { each: true, message: "Указана неверная роль" })
    roles?: string[];

    @ApiProperty({
        type: Boolean,
        description: "Флаг, который показывает, нужно ли сменить пользоватлею пароль",
        example: false
    })
    @AutoMap()
    @IsOptional()
    @ValidateIf((_, value) => !!value)
    @IsBoolean({ message: "Поле needChangePassword должно иметь значение true или false" })
    needChangePassword?: boolean;

    @ApiProperty({
        type: Boolean,
        description: "Флаг, который показывает, заблокирована ли учетная запись",
        example: true
    })
    @AutoMap()
    @IsOptional()
    @ValidateIf((_, value) => !!value)
    @IsBoolean({ message: "Поле isBlocked должно иметь значение true или false" })
    isBlocked?: boolean;
}

export class UpdatePasswordDTO {
    @ApiProperty({
        type: String,
        description: "Старый пароль"
    })
    @AutoMap()
    @IsNotEmpty({ message: "Старый пароль не может быть пустым" })
    oldPassword: string;

    @ApiProperty({
        type: String,
        description: "Новый пароль"
    })
    @AutoMap()
    @IsNotEmpty({ message: "Новый пароль не может быть пустым" })
    @Matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&#])[A-Za-z\d@$!%*?&#]{8,30}$/, {
        message:
            "Новый пароль должен быть от 8 до 30 символов, содержать как минимум одну цифру, строчные и прописные латинские буквы и спецсимволы"
    })
    newPassword: string;
}
